package com.tongtong.stsuserapi.service.register.Impl;

import com.tongtong.stscommon.dto.CaptchaData;
import com.tongtong.stscommon.enumration.Message;
import com.tongtong.stscommon.enumration.Status;
import com.tongtong.stscommon.exception.STSPhoneNumberValidationException;
import com.tongtong.stscommon.exception.STSRegisterException;
import com.tongtong.stscommon.message.STSMessage;
import com.tongtong.stscommon.message.STSSuccessMessage;
import com.tongtong.stscommon.utils.RedisCache;
import com.tongtong.stscommon.utils.TencentCloudSmsUtil;
import com.tongtong.stscommon.utils.checker.cellphoneChecker;
import com.tongtong.stsuserapi.service.register.CaptchaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class CaptchaServiceImpl implements CaptchaService {

	@Autowired
	RedisCache redisCache;

	@Autowired
	TencentCloudSmsUtil tencentCloudSmsUtil;

	private Random random = new Random();

	//第二次申请间隔 60s
	private final long ReapplyDelay = 60 * 1000;

	/**
	 * 发送验证码
	 * @param cellphone 目标手机号
	 */
	@Override
	public STSMessage applyCaptcha(String cellphone) {

		// 手机号格式检查
		if (cellphoneChecker.isInvalidFormat(cellphone))
			throw new STSPhoneNumberValidationException(Status.PhoneNumberIllegal, Message.PhoneNumberInvalid);

		// 重复申请检查
		CaptchaData captcha = redisCache.getCacheObject("captcha:"+cellphone);

		// 若已经申请过验证码
		if (captcha != null) {
			long delta = captcha.getTime().getTime() + ReapplyDelay - new Date().getTime();
			if (delta > 0) // 未到重新申请时间
				throw new STSRegisterException(Status.CaptchaRepeatApply, "验证码重复申请，请于" + delta/1000 + "秒后重试");
		}

		// 生成验证码
		String randomCaptcha = generateCaptcha();
		CaptchaData newCaptcha = new CaptchaData(randomCaptcha,new Timestamp(System.currentTimeMillis()));
		redisCache.setCacheObject("captcha:"+cellphone,newCaptcha,300, TimeUnit.SECONDS);
		// 发送验证码
		tencentCloudSmsUtil.sendCaptcha(cellphone,randomCaptcha);

		return STSMessage.from(Status.OK, Message.OK);
	}

	@Override
	public STSMessage verifyCaptcha(String cellphone, String captcha) {

		// 手机号格式检查
		if (cellphoneChecker.isInvalidFormat(cellphone))
			throw new STSPhoneNumberValidationException(Status.PhoneNumberIllegal, Message.PhoneNumberInvalid);

		CaptchaData originCaptcha = redisCache.getCacheObject("captcha:"+cellphone);
		if (originCaptcha == null)
			throw new STSRegisterException(Status.CaptchaUnapplied, Message.CaptchaUnapplied);
		else if (!originCaptcha.getCaptcha().equals(captcha)) {
			throw new STSRegisterException(Status.CaptchaError, Message.CaptchaError);
		}

		// 验证成功
		redisCache.deleteObject("captcha:"+cellphone);
		return STSSuccessMessage.from(Status.OK, Message.OK);

	}

	/**
	 * 生成6位验证码
	 * @return 验证码字符串
	 */
	private String generateCaptcha() {
		random.setSeed(new Date().getTime()); //随机种子
		List<Integer> rs = new ArrayList<>(6);

		for (int i = 0; i < 6; ++i) {
			rs.add(random.nextInt(10));
		}
		Collections.shuffle(rs); //打乱顺序

		StringBuilder builder = new StringBuilder();
		for (Integer r : rs) {
			builder.append(r);
		}

		return builder.toString();
	}
}
